<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<th:block th:include="common/head :: head('')"/>
<link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css?v=1.18.3}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.7}" rel="stylesheet"/>
<link th:href="@{/css/page/sandbox-detail.css?v=4.7.7}" rel="stylesheet"/>
<th:block th:include="include :: swiper-css"/>
<th:block th:include="include :: swiper-js"/>

<body>
<th:block th:include="common/head :: header('/')"/>

<div class="sandbox-detail page-main">
    <div class="common-block-title" style="margin-bottom: 5px;">
        <img class="common-block-title__ico" src="/img/ico-list1.png"/>
        <span class="common-block-title__txt">基本信息</span>
    </div>
    <div class="sandbox-block">
        <div class="sandbox-block-left">
            <div class="info-name">
                <i class="fa fa-clone"></i> <span id="fileName"></span>
            </div>
            <div class="info-flex">
                <div class="info-flex-left" id="chart"></div>
                <div class="info-flex-right">
                    <div class="info-line">
                        <div class="info-line-label"><i id="osIcon" class="fa fa-windows"></i> 目标平台：</div>
                        <div class="info-line-value" id="os_value"></div>
                    </div>
                    <div class="info-line">
                        <div class="info-line-label"><i class="fa fa-file"></i> 文件类型：</div>
                        <div class="info-line-value" id="file_type_value">exe32</div>
                    </div>
                    <div class="tabList-box" id="tabList-box"></div>
                </div>
            </div>
        </div>
        <div class="sandbox-block-right">
            <div class="right-info">
                <div class="info-line">
                    <div class="info-line-label">检测环境：</div>
                    <div class="info-line-value" id="os_env"></div>
                </div>
                <div class="info-line">
                    <div class="info-line-label">提交时间：</div>
                    <div class="info-line-value" id="added_on"></div>
                </div>
                <div class="info-line">
                    <div class="info-line-label">持续时间：</div>
                    <div class="info-line-value" id="detect_duration"></div>
                </div>
                <div class="info-line">
                    <div class="info-line-label">动态检测：</div>
                    <div class="info-line-value" id="duration"></div>
                </div>
            </div>
        </div>
    </div>
    <div class="sandbox-block">
        <div class="sandbox-block-left info-cards">
            <div class="info-cards-item">
                <div class="card-title">威胁指标</div>
                <div class="card-num" id="threaten_quota">0</div>
                <i class="fa fa-clock-o"></i>
            </div>
            <div class="info-cards-item">
                <div class="card-title">网络主机</div>
                <div class="card-num" id="host">0</div>
                <i class="fa fa-server"></i>
            </div>
            <div class="info-cards-item">
                <div class="card-title">进程数</div>
                <div class="card-num" id="process">0</div>
                <i class="fa fa-sliders"></i>
            </div>
            <div class="info-cards-item">
                <div class="card-title">病毒名</div>
                <div class="card-num" id="virus_name">0</div>
                <i class="fa fa-bug"></i>
            </div>
            <div class="info-cards-item">
                <div class="card-title">释放文件</div>
                <div class="card-num" id="dropped">0</div>
                <i class="fa fa-file"></i>
            </div>
            <div class="info-cards-item">
                <div class="card-title">规则指标</div>
                <div class="card-num" id="signatures_quota">0</div>
                <i class="fa fa-building"></i>
            </div>
        </div>
        <div class="sandbox-block-right">
            <div class="right-info" style="position: absolute;width: 100%; overflow:hidden; margin-top: 20px;">
                <div class="info-line">
                    <div class="info-line-label">MD5：</div>
                    <div class="info-line-value" id="md5"></div>
                </div>
                <div class="info-line">
                    <div class="info-line-label">SHA1：</div>
                    <div class="info-line-value" id="sha1"></div>
                </div>
                <div class="info-line">
                    <div class="info-line-label">SHA256：</div>
                    <div class="info-line-value" id="sha256"></div>
                </div>

            </div>
        </div>
    </div>

    <div class="common-block-title" style="margin-top: 20px; margin-bottom: 5px;">
        <img class="common-block-title__ico" src="/img/ico-list2.png"/>
        <span class="common-block-title__txt">报告详情</span>
    </div>

    <div class="common-block-content" style="padding: 10px;">
        <div class="tabs">
            <div class="tabs-head">
                <div class="tabs-head-item" name="overview">
                  <span>
                      <i class="fa fa-pie-chart"></i> 分析概览
                  </span>
                </div>
                <div class="tabs-head-item" name="jtfx">
                   <span>
                       <i class="fa fa-list"></i> 静态分析
                   </span>
                </div>
                <div class="tab-slider"></div>
            </div>
            <div class="tabs-content">
                <div class="tabs-content-wrapper">
                    <div class="content-item">
                        <div class="collapse">
                            <div class="collapse-item">
                                <div class="collapse-item-head">
                                    <div>智能引擎</div>
                                    <i class="collapse-item__arrow fa fa-angle-right"></i>
                                </div>
                                <div class="collapse-item-content">
                                    <div class="widget-wrap">
                                        <div id="aiengine"></div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="collapse">
                            <div class="collapse-item">
                                <div class="collapse-item-head">
                                    <div>静态判定</div>
                                    <i class="collapse-item__arrow fa fa-angle-right"></i>

                                </div>
                                <div class="collapse-item-content">
                                    <div class="widget-wrap">
                                        <div class="widget-title">
                                            <span>引擎判定</span>
                                            <span class="widget-title-tag" id="yinqin_name"></span>
                                        </div>
                                        <table class="etable">
                                            <thead>
                                            <tr>
                                                <th style="width: 380px;">引擎名称</th>
                                                <th>检出结果</th>
                                            </tr>
                                            </thead>
                                            <tbody id="staticTbody">

                                            </tbody>
                                        </table>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="collapse behavior-feature-wrap">
                            <div class="collapse-item">
                                <div class="collapse-item-head">
                                    <div>行为判定</div>
                                    <i class="collapse-item__arrow fa fa-angle-right"></i>
                                </div>
                                <div class="collapse-item-content">
                                    <div class="widget-wrap three-behavior" id="behavior-feature">

                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="collapse">
                            <div class="collapse-item">
                                <div class="collapse-item-head">
                                    <div>运行截图</div>
                                    <i class="collapse-item__arrow fa fa-angle-right"></i>
                                </div>
                                <div class="collapse-item-content">
                                    <div class="widget-wrap">
                                        <div class="sand-swiper swiper-container " >
                                            <div class="swiper-wrapper sand-swiper__container" id="screenShot"></div>
                                        </div>
                                        <div class="swiper-button-next"></div>
                                        <div class="swiper-button-prev"></div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="collapse">
                            <div class="collapse-item">
                                <div class="collapse-item-head">
                                    <div>网络概要</div>
                                    <i class="collapse-item__arrow fa fa-angle-right"></i>
                                </div>
                                <div class="collapse-item-content">
                                    <div class="widget-wrap" id="network">
                                        <div id="network-head"></div>
                                        <div id="network-content"></div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="collapse">
                            <div class="collapse-item">
                                <div class="collapse-item-head">
                                    <div>行为总览</div>
                                    <i class="collapse-item__arrow fa fa-angle-right"></i>
                                </div>
                                <div class="collapse-item-content">
                                    <div class="widget-wrap">
                                        <div id="summary-head"></div>
                                        <div id="summary-content"></div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="content-item">
                        <div class="collapse">
                            <div class="collapse-item">
                                <div class="collapse-item-head">
                                    <div id="staticName">文件信息</div>
                                    <i class="collapse-item__arrow fa fa-angle-right"></i>
                                </div>
                                <div class="collapse-item-content">
                                    <div class="widget-wrap" id="staticInfo">

                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="collapse">
                            <div class="collapse-item">
                                <div class="collapse-item-head">
                                    <div>PE信息</div>
                                    <i class="collapse-item__arrow fa fa-angle-right"></i>
                                </div>
                                <div class="collapse-item-content">
                                    <div class="widget-wrap" id="staticPe">
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<th:block th:include="common/head :: link"/>
<th:block th:include="common/head :: footer"/>

<!-- bootstrap-table 表格插件 -->
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.7}"></script>
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js?v=2.70.0}"></script>
<script th:src="@{/ajax/libs/echarts.5.4.3/echarts.min.js}"></script>
<th:block th:replace="include :: laypage-js" />
<script th:inline="javascript">
    const taskId = [[${taskId}]]
    const result = [[${result}]]
    const tagData = [[${tags}]] // 标签
</script>
<script src="/js/me/eTab.js"></script>
<script src="/js/me/eCollapse.js"></script>
<script src="/js/me/page/event_description.js"></script>
<script src="/js/me/page/jtfx.js"></script>
</body>
<script th:inline="javascript">

    init()

    function init() {
        const info = result.info || null

        if (!result || !info) {
            $.modal.alert('尚未检测完成，请稍后再试!')
            return
        }


        initChart(info)
        initInfo(info)

        initFxgl() // 分析概览
        initJtfx() // 静态分析

        initTab() // 最顶层的tab
    }

    // tab切换
    function initTab() {
        $('.tabs').eTab()
        $('.collapse').eCollapse()

        // 默认收缩 行为判定
        const eCollapse = $('.behavior-feature-wrap').data('eCollapse')
        if(eCollapse) {
            eCollapse.setCollapsed(true)
        }
    }

    // gauge图
    function initChart(info) {
        const combine = info.score
        let scoreType = {label: '未发现威胁', value: '#00ab7a'}
        if (combine > 4.9) {
            scoreType = {label: '可疑', value: '#e69f32'}
        } else if (combine > 7.4) {
            scoreType = {label: '恶意', value: '#ff5967'}
        }

        const gaugeData = [
            {
                value: combine * 10,
                name: scoreType.label,
                title: {
                    offsetCenter: ['0%', '135%'],
                    color: scoreType.value,
                    fontSize: 14,
                    fontFamily: 'PdfPingFang'
                },
                itemStyle: {
                    color: scoreType.value
                }
            }
        ]

        var myChart = echarts.init(document.getElementById('chart'), null, {renderer: 'svg'});
        const option = {
            grid: {
                top: 20,
                bottom: 10
            },
            tooltip: {
                show: false,
                formatter: '{a} <br/>{b} : {c}%'
            },
            // 标题
            title: [
                {
                    text: gaugeData[0].value / 10,
                    x: 'center',
                    y: 45,
                    textStyle: {
                        fontSize: '25',
                        color: scoreType.value,
                        fontFamily: 'DIN Alternate',
                        foontWeight: '600'
                    }
                }
            ],

            series: [
                // 内圆
                {
                    type: 'pie',
                    radius: '53%',
                    center: ['50%', '40%'],
                    animation: false,
                    z: 3,
                    itemStyle: {
                        shadowColor: 'red',
                        shadowBlur: 12,
                        normal: {
                            color: '#fff',
                            label: {
                                show: false
                            },
                            labelLine: {
                                show: false
                            },
                            borderColor: '#fff',
                            shadowBlur: 10,
                            shadowColor: '#0000001f',
                            borderWidth: 2
                        }
                    },
                    hoverAnimation: false,
                    label: {
                        show: false
                    },
                    tooltip: {
                        show: false
                    },
                    data: [100]
                },
                {
                    type: 'gauge',
                    center: ['50%', '40%'],
                    startAngle: 90,
                    endAngle: -270,
                    pointer: {
                        show: false
                    },
                    progress: {
                        show: true,
                        overlap: false,
                        roundCap: true,
                        clip: false,
                        itemStyle: {
                            borderWidth: 0
                        }
                    },
                    axisLine: {
                        show: false,
                        lineStyle: {
                            width: 6
                        }
                    },
                    splitLine: {
                        show: false,
                        distance: 0,
                        length: 10
                    },
                    axisTick: {
                        show: false
                    },
                    axisLabel: {
                        show: false,
                        distance: 50
                    },
                    data: gaugeData,
                    title: {
                        fontSize: 14,
                        offsetCenter: ['0', '100%']
                    }
                },
                {
                    radius: '65%',
                    center: ['50%', '40%'],
                    type: 'gauge',
                    startAngle: 90,
                    endAngle: -270,
                    pointer: {
                        show: false
                    },
                    animation: false,
                    progress: {
                        show: true,
                        overlap: false,
                        roundCap: true,
                        clip: false,
                        itemStyle: {
                            borderWidth: 0,
                            color: '#F8FBFE'
                        }
                    },
                    axisLine: {
                        show: false,
                        lineStyle: {
                            width: 9
                        }
                    },
                    splitLine: {
                        show: false,
                        distance: 0,
                        length: 10
                    },
                    axisTick: {
                        show: false
                    },
                    axisLabel: {
                        show: false,
                        distance: 50
                    },
                    data: [100]
                },
                // 外圆
                {
                    type: 'pie',
                    radius: '72%',
                    center: ['50%', '40%'],
                    animation: false,
                    z: 0,
                    itemStyle: {
                        normal: {
                            color: '#E8EAED',
                            label: {
                                show: false
                            },
                            labelLine: {
                                show: false
                            },
                            borderColor: '#fff',
                            shadowBlur: 10,
                            shadowColor: '#0000002d',
                            borderWidth: 2
                        }
                    },
                    hoverAnimation: false,
                    label: {
                        show: false
                    },
                    tooltip: {
                        show: false
                    },
                    data: [100]
                }
            ]
        }
        myChart.setOption(option);
    }

    // 上面基本信息
    function initInfo(info) {
        const os = info.machine.os
        const filename = info.filename
        const file_type = info.file_type

        $('#osIcon').removeClass().addClass('fa fa-' + os.toLowerCase())
        $('#os_value').html(os)
        $('#fileName').html(filename)
        $('#file_type_value').html(file_type)

        const os_env = info.os_env || ''

        $('#os_env').html(os_env.replaceAll(',', ''))
        $('#added_on').html(info.added_on || '')
        $('#detect_duration').html((info.detect_duration || '') + '秒')
        $('#duration').html((info.duration || '') + '秒')

        // 标签
        const tags = tagData.tags || []
        const tagHtmls = []

        tags.forEach(item => {
            const severity = item.severity
            const label = item.tagzhcn || item.name
            let clas = ''

            if (severity <= 1) {
                clas = 'tabList-item--low'
            } else if (severity === 2) {
                clas = 'tabList-item--middle'
            } else if (severity >= 3) {
                clas = 'tabList-item--high'
            }
            tagHtmls.push('<div class="tabList-item ' + clas + '">')
            tagHtmls.push(label)
            tagHtmls.push('</div>')
        })
        $('#tabList-box').html(tagHtmls.join(''))

        // 指标
        const specific_quota_count = result.specific_quota_count || {}
        Object.keys(specific_quota_count).forEach(key => {
            $('#' + key).html(specific_quota_count[key])
        })

        // zserver
        const zserver = result.zserver || {}
        $('#md5').html(zserver.md5)
        $('#sha1').html(zserver.sha1)
        $('#sha256').html(zserver.sha256)
    }

    /* ---------- 分析概览 --------------*/
    // 分析概览
    function initFxgl() {
        // 智能引擎
        const aiengine = result.aiengine || {}
        const detect = aiengine.detect || []

        const aiengineHtml = []
        detect.forEach(function (item) {
            aiengineHtml.push('<div class="aiengine-item">')
            aiengineHtml.push('<div class="name">')
            aiengineHtml.push(item.name)
            aiengineHtml.push('</div>')
            aiengineHtml.push('<div class="score">')
            aiengineHtml.push(item.score)
            aiengineHtml.push('</div>')
            aiengineHtml.push('</div>')
        })

        $('#aiengine').html(aiengineHtml.join(''))

        // 静态判定
        const zserver = result.zserver || {}
        const detail_info = zserver.detail_info || {}
        const threat_level = zserver.threat_level

        const engineKeyMap = {
            qvm_info: '人工智能引擎',
            aqvm_info: '人工智能引擎（移动版）',
            bd_info: '增强型查杀引擎Ⅰ',
            sign_info: '签名扫描引擎',
            avira_info: '增强型查杀引擎Ⅱ',
            ave_info: '启发式查杀引擎',
            kpav_info: '鲲鹏查杀引擎',
            avm_info: '启发式查杀引擎（移动版）',
            qex_info: '脚本查杀引擎',
            cloud_info: '增强型查杀引擎Ⅲ'
        }

        const getLevel = function () {
            if (!result.zserver) {
                return {name: '未检出', type: ''}
            }

            switch (threat_level) {
                case 70:
                    return {name: '恶意', type: 'red', color: '#ff5967'}
                case 50:
                    return {name: '可疑', type: 'orange', color: 'orange'}
                case 40:
                    return {name: '未检出', type: ''}
                case 10:
                    return {name: '无风险', type: 'green', color: '#00ab7a'}
                default:
                    return {name: '未检出', type: ''}
            }
        }
        const getTableData = () => {
            const virusList = []
            if (Object.keys(detail_info).length === 0) {
                return []
            }

            if (threat_level === 50 || threat_level === 70) {
                for (const [key, val] of Object.entries(detail_info)) {
                    if (val.scan_status === 1 || val.scan_status === 3) {
                        virusList.push({
                            engine_name: engineKeyMap[key],
                            scan_status: val.scan_status,
                            virus_name: {
                                color: val.scan_status === 1 ? '#F34E4E' : 'orange',
                                value: val.virus_name
                            }
                        })
                    }
                }
            } else if (threat_level === 10 || threat_level === 20) {
                for (const key of ['cloud_info', 'sign_info']) {
                    if (detail_info[key].scan_status === 2) {
                        virusList.push({
                            engine_name: engineKeyMap[key],
                            scan_status: detail_info[key].scan_status,
                            virus_name: {
                                color: '#00ab7a',
                                value: detail_info[key].cn
                            }
                        })
                    }
                }
            }

            return virusList.filter((item) => item.engine_name)
        }
        const scanType = (status) => {
            switch (status) {
                case 1:
                    return 'high'
                case 2:
                    return 'low'
                case 3:
                    return 'middle'
                default:
                    return 'low'
            }
        }
        const icoType = (status) => {
            switch (status) {
                case 1:
                    return 'fa-bug'
                case 2:
                    return 'fa-check-circle'
                case 3:
                    return 'fa-bug'
                default:
                    return 'fa-check-circle'
            }
        }

        const level = getLevel()
        const tableData = getTableData()

        const trs = []
        tableData.forEach(item => {
            let tdCls = scanType(item.scan_status)
            let ico = icoType(item.scan_status)

            trs.push('<tr> <td>')
            trs.push('<i class="yinqin fa fa-shield"></i>')
            trs.push(item.engine_name)
            trs.push('</td>')
            trs.push('<td class="' + tdCls + '">')
            trs.push('<i class="fa ' + ico + '"></i>')
            trs.push(item.virus_name.value)
            trs.push('</td></tr>')
        })


        $('#staticTbody').html(trs.join(''))
        $('#yinqin_name').addClass(level.type).html(level.name)

        // 行为判定
        initBehavior()
        // 运行截图
        initScreenShots()
        // 网络概要
        initNetworks()
        // 行为总览
        initBehaviorSummary()
    }

    // 行为判定
    function initBehavior() {
        const keyMap = eventdesc
        const behavior_signatures_genre = result.behavior_signatures_genre || []

        // 转换数据
        const convertSignature = behavior_signatures_genre.map(item => {
            return {
                title: item.titlezhcn,
                lockData: item.count,
                childrenData: item.data.sort((a, b) => {return  b.severity - a.severity}).map(item2 => {
                    return {
                        title: `${item2.descripzhcn} (${item2.marks.length}个事件)`,
                        type: item2.severity === 1 ? 'low' : (item2.severity === 2 ? 'middle' : 'high'),
                        desc: item2.descripzhcn,
                        severity: item2.severity,
                        childrenData: {
                            marks: item2.marks,
                            attackid: item2.attackid
                        }
                    }
                })
            }
        })

        // 切割字符串
        const attackidSep = (str) => {
            if (str) {
                return str.split(',')
            } else {
                return []
            }
        }

        // 唉，当成组件吧
        const ListExtend = (list) => {
            const dataType = Object.prototype.toString
                .call(list)
                .slice(8, -1)
                .toLowerCase()
            const argumentsList = event_description.argument
            const getArguments = (index) => {
                return (argumentsList[index] && argumentsList[index].zhcn) || index
            }


            const html = []
            html.push('<div class="list-extend-wrap">')

            if(dataType === 'array') {
                html.push('<div class="list-array">')
                html.push(' <pre>'+ list.join('\n') +'</pre>')
                html.push('</div>')
            } else {
                list.forEach((item, index) => {
                    html.push('<div class="list-extend-item">')
                    html.push(' <span class="label">'+ getArguments(index) +'</span>')
                    html.push(' <span class="value">'+ item +'</span>')
                    html.push('</div>')
                })
            }
            html.push('</div>')
            return html.join('')
        }

        // 把这玩意当一个vue组件吧
        const BehaviorEvents = (events) => {
            const arr = []
            const eventList = event_description.event
            const argumentsList = event_description.argument

            const getEventName = (event) => {
                const eventName = eventList[event]
                return eventName?.zhcn || event
            }
            const getArguments = (index) => {
                return (argumentsList[index] && argumentsList[index].zhcn) || index
            }
            const getFlagsType = (obj) => {
                return Object.prototype.toString
                    .call(obj)
                    .slice(8, -1)
                    .toLowerCase()
            }
            const getValue = (item, item2) => {
                return item || item2
            }

            arr.push('<div class="behavior-events-wrap">')
            if(events.length > 0) {
                events.forEach(item => {
                    arr.push('<div class="behavior-event-item">')
                    arr.push('  <div class="behavior-event-left">')
                    arr.push('      <div class="event-name-wrap">')
                    arr.push('         <span class="event-name">' + getEventName(item.event.event) + '</span>')
                    arr.push('      </div>')
                    arr.push('      <div class="event-time-wrap">')
                    arr.push('           <span class="event-time">+'+item.event.sec+'s</span>')
                    arr.push('      </div>')
                    arr.push('  </div>')
                    arr.push('  <div class="behavior-event-right">  ')
                    if(item.event.mainkey) {
                        arr.push(' <div class="behavior-event-right_mainkey">' + item.event.mainkey + '</div>')
                    }

                    Object.keys(item.event.arguments).forEach(key => {
                        const arg =  item.event.arguments[key]
                        arr.push('  <div class="behavior-event-right_event">')
                        arr.push('      <div class="behavior-event-right_event-label">'+ getArguments(key) +'</div>')

                        if(getFlagsType(item.event.flags[key]) === 'array') {
                            arr.push('      <div class="behavior-event-right_event-value behavior-event-right_event-marginTop">')
                            const obj = getValue(item.event.flags[key], item.event.arguments[key])
                            for(flagKey in obj) {
                                arr.push('     <span class="value-item" title="' + item.event.arguments[key] + '">' + obj[flagKey] + '</span>')
                            }
                            arr.push('      </div>')
                        } else {
                            arr.push('      <div class="behavior-event-right_event-value">')
                            if(getFlagsType(getValue(item.event.flags[key], item.event.arguments[key])) === 'array' ||
                                getFlagsType(getValue(item.event.flags[key], item.event.arguments[key])) === 'object') {

                                arr.push(ListExtend(getValue(item.event.flags[key], item.event.arguments[key])))
                            } else {
                                arr.push(' <div>' + getValue(item.event.flags[key], item.event.arguments[key]) + '</div>')
                            }
                            arr.push('</div>')
                        }
                        arr.push('</div>')
                    })


                    arr.push('      <div class="behavior-event-right_return">')
                    arr.push('          <div class="behavior-event-right_return-left">')
                    arr.push('              <span class="behavior-event-right_return-left-label">返回值</span>')
                    arr.push('              <span class="behavior-event-right_return-left-value">' +  item.event.return_value + '</span>')
                    arr.push('          </div>')
                    arr.push('          <div class="behavior-event-right_return-right">')
                    arr.push('              <span>'+ (item.event.status === 1 ? '成功' : '失败')  +'</span>')
                    if(item.event.repeated) {
                        arr.push('          <span class="behavior-event-right_return-right-repeat">重复' + item.event.repeated + '次</span>')
                    }
                    arr.push('          </div>')
                    arr.push('      </div>')
                    arr.push('  </div>')
                    arr.push('</div>')
                })
            }
            arr.push('</div>')

            return arr.join('')
        }

        const handleTableData  = (list) => {
            if (list.length === 0) {
                return { columnData: [], tableData: [] }
            }
            const copyList = JSON.parse(JSON.stringify(list))
            let columnData
            let tableData
            const type = copyList[0].type
            if (type === 'call') {
                // 带表头的横向表格
                columnData = [
                    {
                        prop: 'time',
                        label: '事件',
                        col: 2
                    }, {
                        prop: 'arguments',
                        label: '参数',
                        col: 3
                    }, {
                        prop: 'status',
                        label: '状态'
                    }, {
                        prop: 'return_value',
                        label: '返回值'
                    }, {
                        prop: 'pid',
                        label: '进程'
                    }, {
                        prop: 'tid',
                        label: '线程'
                    }, {
                        prop: 'repeated',
                        label: '重复'
                    }
                ]
                tableData = copyList.map(item => ({
                    ...item.call,
                    time: `<span>${item.call.time}</span><br /><span style="font-weight: bold;">${item.call.api}</span>`,
                    arguments: Object.keys(item.call.arguments).map(key => {
                        return `<span>${key}: ${item.call.arguments[key]}</span>`
                    }).join('<br/>'),
                    status: item.call.status ? '成功' : '失败'
                }))
            }
            else if (type === 'generic') {
                // 纵向表头
                const result = copyList.map(item => {
                    delete item.type
                    return item
                })
                columnData = Object.keys(result[0]).map(item => ({
                    prop: item,
                    label: keyMap[item] || item,
                    titleWidth: '120'
                }))
                tableData = result
            }
            else {
                columnData = [{
                    prop: 'ioc',
                    label: keyMap[copyList[0].category] || copyList[0].category,
                    titleWidth: '120'
                }]
                tableData = copyList
            }
            return { columnData, tableData, tableProps: { isHorizontal: type !== 'call' } }
        }

        const SandTable = (marks) => {
            const data = handleTableData(marks)

            const showHeader = (function() {
                if (data.tableData.length === 0 || data.columnData.length === 0) {
                    return false
                }
                if (data.tableProps.isHorizontal) {
                    return false
                }
                if (data.tableProps.showHeader === undefined) {
                    return true
                }
                return thdatais.tableProps.showHeader
            })()
            const tableDataFn = () => {
                if (data.tableData) {
                    if (data.tableProps.isHorizontal) {
                        const columnTableData = []
                        // 把数据和结构合并一下,变成一行中表头和内容间隔的数据格式
                        // 在渲染的时候就只需要循环这个数组就可以渲染整个数据了
                        // 因为采用普通的两个数组循环就得一次循环得到一个表头一个内容
                        // 然后采用flex布局的话一个表头一个内容在一个循环的框里,布局会有问题
                        data.tableData.forEach((item, index) => {
                            columnTableData.push([])
                            data.columnData.forEach(column => {
                                // 如果是表头的话就会标识一下,如果内容为空会给他一个空,防止undefined后面调用的时候报错
                                columnTableData[index].push(
                                    {
                                        ...column,
                                        isTitle: true,
                                        width: column.titleWidth,
                                        col: column.titleCol,
                                        align: column.titleAlign || column.align,
                                        val: column.label
                                    },
                                    {
                                        ...column,
                                        val: item[column.prop] === undefined ? '' : item[column.prop]
                                    }
                                )
                            })
                        })
                        return columnTableData
                    }
                    return data.data.tableData
                }
                return []
            }
            const tableData = tableDataFn()

            const getWidth = (data) => {
                if (data.indexOf('px') > 0) {
                    return data
                }
                return data + 'px'
            }

            const html = []
            html.push('<div class="sand-newTable attck-table">')
            html.push(' <div class="sand-newTable__table">')

            if(showHeader) {
                html.push('<div class="newTable__header">')
                    data.columnData.forEach(item => {
                        const style = `
                            width: ${item.width ? getWidth(item.width) : '0px'};
                            flex-grow: ${item.width ? '0' : (item.col ? item.col : '1')};
                            text-align: ${item.align ? item.align : 'left'}
                        `
                        html.push('<div class="sand-newTable__header--item" style="' + style +'">')
                            html.push('<span class="sand-newTable__header--text">')
                            html.push(`<span>${item.label}</span>```)
                            html.push('</span>')
                        html.push('</div>')
                    })
                html.push('</div>')
            }

            html.push('  <div class="sand-newTable__body">')

            tableData.forEach((tr, index) => {
                html.push('<div class="sand-newTable__body--tr">')
                let tds = tr
                /*   如果是水平的话就是循环tr就可以了  */
                if(!data.tableProps.isHorizontal) {
                    tds = data.columnData
                }

                tds.forEach((td, tdIndex) => {
                    const style = `
                        width: ${td.width ? getWidth(td.width) : '0px'};
                        flex-grow: ${td.width ? '0' : (td.col ? td.col : '1')};
                        text-align: ${td.align ? td.align : 'left'};
                    `
                    html.push(' <div class="sand-newTable__body--td ' + (data.tableProps.isHorizontal ? 'sand-newTable__body--horizontalTd': '') + '" style="' + style +'">')
                    /* 水平的数据在每一项的val里 */
                    if(td.type === 'border' && !td.isTitle) {
                        const _style = `
                            border-color: ${data.tableProps.isHorizontal ? td.val.color : tr[td.prop].color};
                            color: ${data.tableProps.isHorizontal ? td.val.color : tr[td.prop].color};
                        `
                        html.push('<span class="sand-newTable__body--border" style="'+_style+'">')
                        html.push(data.tableProps.isHorizontal ? td.val.value : tr[td.prop].value)
                        html.push('</span>')
                    } else if(td.html) {
                        html.push('<span class="sand-newTable__body--text">')
                        html.push(data.tableProps.isHorizontal ? td.val : tr[td.prop])
                        html.push('</span>')
                    } else {
                        html.push('<span class="sand-newTable__body--text">')
                        html.push(data.tableProps.isHorizontal ? td.val : tr[td.prop])
                        html.push('</span>')
                    }
                    html.push('</div>')
                })
                html.push('</div>')
            })
            html.push('   </div>')

            html.push(' </div>')
            html.push('</div>')
            return html.join('')
        }

        const htmls = []
        const checkId = 'behavior'
        convertSignature.forEach((item, index) => {
            const inputId = checkId + '_' + index
            if(!item.childrenData && item.lockData <= 0 ) {
                return
            }

            htmls.push('<div class="sand-gradeCollapseGroup">')
            if(item.title) {
                htmls.push('<div class="widget-title">'+item.title+'</div>')
            }
            htmls.push('<div class="sand-gradeCollapseGroup__box">')

            const childHtmls = []
            item.childrenData.forEach((child, cIndex) => {
                childHtmls.push('<div class="my-collapse">')
                childHtmls.push('    <div class="my-collapse-item">  ')
                childHtmls.push('        <input type="checkbox" id="'+inputId+cIndex+'" />')
                childHtmls.push('        <label class="sand-gradeCollapseGroup__header sand-gradeCollapseGroup__header--'+child.type+' my-collapse-item__header" for="' + inputId +cIndex + '" >')
                childHtmls.push(            child.title)
                childHtmls.push('       </label>')
                childHtmls.push('   <div class="my-collapse-item__content">')

                const attackids = attackidSep(child.childrenData.attackid)

                if(attackids.length > 0) {
                    childHtmls.push(' <div class="attck-id">     ')
                    childHtmls.push('   <span>ATT&CK ID：</span> ')
                    attackids.forEach(id => {
                        childHtmls.push('<span class="attck-id-item">' + id + '</span>')
                    })
                    childHtmls.push('</div>')
                }
                if(child.childrenData.marks[0] && child.childrenData.marks[0].type !== 'event') {
                    childHtmls.push(SandTable(child.childrenData.marks))
                } else {
                    childHtmls.push(BehaviorEvents(child.childrenData.marks))
                }

                childHtmls.push('</div>')
                childHtmls.push('</div>')
                childHtmls.push('</div>')
            })

            htmls.push(childHtmls.join(''))
            htmls.push('</div>')

        })

        $('#behavior-feature').html(htmls.join(''))
    }

    // 运行截图
    function initScreenShots() {
        $.get(ctx +'serve/sandboxScreenshot/' + taskId, function(res) {
            if(res.code !== 0) {
                return
            }

            if(!res.data || !res.data.shots) {
                return
            }

            const list = res.data.shots || []
            const host = 'https://ata.360.net'

            const htmls = []
            const len = list.length
            list.forEach((item, index) => {
                htmls.push('<div class="swiper-slide">')
                htmls.push('    <div class="sand-swiper__container--box">')
                htmls.push('        <div class="sand-swiper__container--item">')
                htmls.push(`            <img class=sand-swiper__container--img src="${host + item}"/>`)
                htmls.push(`            <div class="sand-swiper__container--bottom">${index + 1}/${len}</div>`)
                htmls.push('        </div>')
                htmls.push('    </div>')
                htmls.push('</div>')
                htmls.push('')
            })

            $('#screenShot').html(htmls.join(''))
            var swiper = new Swiper('.swiper-container', {
                navigation: {
                    nextEl: '.swiper-button-next',
                    prevEl: '.swiper-button-prev'
                },
                slidesPerView: 6
            })

            $('.sand-swiper__container--img').on('click', function() {
                const index = $('.sand-swiper__container--img').index(this)
                const data = []

                $('.sand-swiper__container--img').each(function() {
                    data.push({
                        src: $(this).attr('src')
                    })
                })
                layer.photos({
                    photos: {
                        title: '运行截图',
                        start: index,
                        data: data
                    }
                })
            })

        })
    }

    // 网络概要
    function initNetworks() {
        var networkCount
        const getColumnData = () => {
            const overviewColumnData = {
                'traffic.alerts': [
                    {
                        prop: 'src_ip',
                        label: '源IP地址',
                        align: 'left'
                    },
                    {
                        prop: 'dst_ip',
                        label: '目的IP地址',
                        align: 'left'
                    },
                    {
                        prop: 'category',
                        label: '类型',
                        align: 'left'
                    },
                    {
                        prop: 'severity',
                        label: '严重程度',
                        align: 'left'
                    }
                ],
                hosts: [
                    {
                        prop: 'ip',
                        label: 'IP地址',
                        align: 'left'
                    },
                    {
                        prop: 'country',
                        label: '国家或地区',
                        align: 'left'
                    },
                    {
                        prop: 'city',
                        label: '城市',
                        align: 'left'
                    },
                    {
                        prop: 'isp',
                        label: 'ISP',
                        align: 'left'
                    }
                ],
                dns: [
                    {
                        prop: 'area_name',
                        label: '域名',
                        align: 'left'
                    },
                    {
                        prop: 'analyse',
                        label: '解析结果',
                        align: 'left'
                    }
                ]
            }
            if (networkCount['traffic.alerts'] === 0) {
                delete overviewColumnData['traffic.alerts']
            }
            return overviewColumnData
        }
        const getTabData = (columnData) => {
            const keys = Object.keys(columnData)
            const cn = {
                'traffic.alerts': '流量检测',
                hosts: '主机',
                dns: '域名'
            }
            const resultData = keys.map(item => {
                let label = `${item.toUpperCase()}(${networkCount[item]})`
                for (const key in cn) {
                    if (key === item) {
                        label = `${cn[key]}(${networkCount[item]})`
                    }
                }
                return {
                    label,
                    name: item
                }
            })
            return resultData
        }


        const sandNetwork = function(tab, columnData, networkCount) {
            const header = columnData[tab]
            const totalCount = networkCount[tab]

            const getWidth = (data) => {
                if (data.indexOf('px') > 0) {
                    return data
                }
                return data + 'px'
            }
            const isEmpty = (target) => {
                const type = Object.prototype.toString.call(target).slice(8, -1).toLowerCase()
                switch (type) {
                    case 'object':
                    case 'array':
                    case 'string':
                        return Object.keys(target).length === 0
                    case 'undefined':
                    case 'null':
                        return true
                    default:
                        return false
                }
            }

            const riskStyle = (data) => {
                switch (data) {
                    case 3:
                        return { name: '低危', border: '#5a5e6d', color: '#b8bbcc' }
                    case 2:
                        return { name: '中危', border: '#c2aa6f', color: '#d9b12f' }
                    case 1:
                        return { name: '高危', border: '#eb726c', color: '#ff6a63' }
                    default:
                        return { name: '未检出', border: '', color: '#5a5e6d' }
                }
            }

            const loadNetWork = (page, tab) => {
                fetchNetWork({page: page, size: 10, protocol: tab}).then(res => {
                    laypage({
                        cont: 'pageEl',
                        curr: page,
                        pages: Math.ceil(networkCount[tab] / 10),
                        jump: function(obj, first){
                            if(!first) {
                                loadNetWork(obj.curr)
                            }
                        }
                    })

                    let networkData = []
                    if (!isEmpty(res.network[tab])) {
                        if (tab === 'dns') {
                            networkData = res.network.dns.map(item => {
                                return {
                                    area_name: item.request,
                                    response: item.answers.map(item => `${item.type} ${item.data}`).join('\n'),
                                    analyse: res.network.domainlookups[item.request]
                                }
                            })
                        } else if (tab === 'traffic.alerts') {
                            networkData = res.network[tab].map(item => {

                                return {
                                    ...item.alert,
                                    ...item,
                                    timestamp: item.timestamp ? date(new Date(item.timestamp), 'yyyy-MM-dd hh:mm:ss') + '.' + item.timestamp.split('.')[1].split('+')[0] : '-'
                                }
                            })
                        } else if (tab === 'ftp') {
                            res.network.ftp.map(v => {
                                v.cmd = v.cmd.join('\n')
                                return v
                            })
                            networkData = res.network[tab]
                        } else {
                            networkData = res.network[tab]
                        }
                    } else {
                        networkData = []
                    }

                    const listHtml = []
                    networkData.forEach((collapse, index) => {
                        listHtml.push('<div class="sand-tableCollapse__header">')
                        listHtml.push('<div class="sand-tableCollapse__header--item">')

                        header.forEach((item2,index2) => {
                            let style = `
                                width: ${item2.width ? getWidth(item2.width) : '0px'};
                                flex-grow: ${item2.width ? '0' : item2.col ? item2.col : '1'};
                                text-align: ${item2.align ? item2.align : 'left'};
                            `
                            listHtml.push('<span class="sand-tableCollapse__header--text" style="'+style+'">')

                            if(item2.prop === 'severity') {
                                const style2 = `
                                    color: ${riskStyle(collapse[item2.prop]).color};
                                    border-color: ${riskStyle(collapse[item2.prop]).border};
                                `
                                listHtml.push('<span class="sand-tableCollapse__header--tags" style="'+style2+'">'+ riskStyle(collapse[item2.prop]).name +'</span>')
                            } else {
                                listHtml.push('<span class="font">' + collapse[item2.prop] + '</span>')
                            }


                            listHtml.push('</span>')
                        })
                        listHtml.push('</div>')
                        listHtml.push('</div>')
                    })

                    $('#sandNetwork-content').html(listHtml.join(''))
                })
            }

            const htmls = []
            htmls.push('<div class="sandNetwork-table">')
            htmls.push('<div class="sandNetwork-header">')


            header.forEach(item => {
                const style = `
                    width: ${item.width ? getWidth(item.width) : '0px'};
                    flex-grow: ${item.width ? '0' : item.col ? item.col : '1'};
                    text-align: ${item.align ? item.align : 'left'};
                `
                htmls.push('<span class="header-col">')
                htmls.push(item.label)
                htmls.push('</span>')
            })
            htmls.push('</div>')
            htmls.push('<div id="sandNetwork-content"></div>')
            htmls.push('<div class="page-wrap" id="pageEl"></div>')
            htmls.push('</div>')

            $('#network-content').html(htmls.join(''))

            loadNetWork(1, tab)

        }

        fetchNetWork({total: true}).then(data => {
            networkCount = data.network
            const columnData = getColumnData()
            const tabData = getTabData(columnData)
            console.info('tabData:', tabData)

            const tabHtml = ['<div class="tabs tabs-mini">']
            tabHtml.push('<div class="tabs-head">')
            tabData.forEach((item, index) => {
                const clas = index === 0 ? 'active' : ''
                tabHtml.push('<div class="tabs-head-item ' + clas + '" name="' + item.name + '"> <span>')
                tabHtml.push(item.label)
                tabHtml.push('</span></div>')
            })
            tabHtml.push('<div class="tab-slider"></div>')
            tabHtml.push('</div>')
            tabHtml.push('</div>')

            $('#network-head').html(tabHtml.join(''))
            $('#network-head').eTab({
                callback: {
                    onClick: ($el) => {
                        console.info('click', $el)
                        const name = $el.attr('name')
                        sandNetwork(name, columnData, networkCount)
                    }
                }
            })
            // network-content
            if(tabData.length > 0) {
                sandNetwork(tabData[0].name, columnData, networkCount)
            }
        })


    }
    // 网络概要-请求接口
    function fetchNetWork(param) {
        return new Promise(function(resolve, reject) {
            $.get(ctx + 'serve/sandboxNetwork/' + taskId, param, function(res) {
                if(res.code === 0) {
                    resolve(res.data)
                } else {
                    console.error(res.msg)
                }
            })
        })
    }

    // 行为总览
    function initBehaviorSummary() {
        $.get(ctx + 'serve/sandboxBehaviorProcess/' + taskId, function(res) {
            console.info('res-initBehaviorSummary:', res)
            const d = res.data
            const eventsMap = {}
            for (const item of event_description.category) {
                eventsMap[item.name] = item.zhcn
            }
            const keyMap =  Object.keys(d.events_map).length > 0 ? d.events_map : eventsMap
            const progressanalyse = {}
            progressanalyse.process_tree = d.processtree
            progressanalyse.processes = d.processes
            progressanalyse.tab_data = Object.keys(d.events_overview).length > 0 && d.events_overview.map((item) => ({ ...item, name: keyMap[item.key] }))
            progressanalyse.taskOS = result.info.machine.os

            doBehaviorSummary(progressanalyse)
        })
    }

    function doBehaviorSummary(progressanalyse) {
        const getTabData = () => {
            // 如果后端没有返回每个类型的数量, 则使用固定的tab表头
            if (progressanalyse.tab_data) {
                return progressanalyse.tab_data.map((item) => {
                    return {
                        label: `${item.name} (${item.value})`,
                        name: item.key
                    }
                })
            }
            return []
        }
        const getCollapseData = () => {
            const hasDataProcess = processes.filter(
                (processItem) =>
                    processItem.events_info.find((events) => events.key === eventType) &&
                    processItem.events_info.find((events) => events.key === eventType).value
            )
            const collapseData = hasDataProcess.map((item) => ({
                process: `${item.process_name} (进程ID: ${item.pid})`,
                id: item.pid
            }))
            return {
                collapseData,
                columnData: [
                    {
                        prop: 'process',
                        label: '进程名',
                        width: undefined,
                        align: 'left',
                        headAlign: 'left'
                    }
                ],
                tableProps: {
                    stripe: false,
                    showHeader: false
                }
            }
        }
        var tabData = getTabData()
        var taskOS = progressanalyse.taskOS
        var processes = progressanalyse.processes || []

        var argumentsList = event_description.argument
        var eventList = event_description.event
        var category = event_description.category.slice(0, 6)
        var defaultName = progressanalyse.tab_data ? progressanalyse.tab_data[0].key : 'file'
        var eventType = progressanalyse.tab_data ? progressanalyse.tab_data[0].key : 'file'
        var pid = processes.length > 0 ? processes[0].pid : ''

        var collapseData = getCollapseData()

        $('#summary-head')

        // tab
        const buildTabs = () => {
            const html = []
            html.push('<div class="tabs tabs-mini">')
            html.push('<div class="tabs-head">')
            tabData.forEach((tab, index) => {
                let clas = ''
                if(index === 0) {
                    clas = 'active'
                }
                html.push('<div class="tabs-head-item ' + clas + '" name="' + tab.name + '"><span>' + tab.label + '</span></div>')
            })
            html.push('<div class="tab-slider"></div>')
            html.push('</div>')
            html.push('</div>')

            $('#summary-head').html(html.join(''))
            $('#summary-head').eTab({
                callback: {
                    onClick: ($el) => {
                        const name = $el.attr('name')
                        if(eventType === name) {
                            return
                        }
                        eventType = name
                        collapseData = getCollapseData()
                        SandTableCollapse2(collapseData)
                    }
                }
            })
        }

        // 折叠
        const SandTableCollapse2 = (data) => {
            const html = []
            const columnData = data.columnData || []
            const collapseData = data.collapseData || []
            const getTableProps = () => {
                if (this.data) {
                    return this.data.tableProps || {}
                }
                return {}
            }
            const getWidth = (data) => {
                if (data.indexOf('px') > 0) {
                    return data
                }
                return data + 'px'
            }

            const tableProps = getTableProps()
            html.push('<div class="sand-tableCollapse">')

            if(tableProps.showHeader) {
                html.push('<div class="sand-tableCollapse__tableHeader">')

                columnData.forEach(item => {
                    const style = `
                         width: ${item.width ? getWidth(item.width) : '0px'};
                         flex-grow: ${item.width ? '0' : item.col ? item.col : '1'};
                         text-align: ${item.headAlign ? item.headAlign : item.align ? item.align : 'left'};
                    `
                    html.push('<div class="sand-tableCollapse__tableHeader--item" style="' + style + '">')
                    html.push('<span class="sand-tableCollapse__tableHeader--text">' + item.label + '</span>')
                    html.push('</div>')
                })
                html.push('</div>')
            }

            html.push('<div class="sand-tableCollapse behavior-summary-collapse">')
            collapseData.forEach((collapse, index) => {
                const _id = 'behavior_summary_' + index +
                html.push('<div class="my-collapse">')
                html.push(' <div class="my-collapse-item">')
                html.push('  <input type="checkbox" id="' + _id + '" />')
                html.push('  <label class="sand-tableCollapse__header" for="' + _id + '">')

                columnData.forEach(item => {
                    const style = `
                        width: ${item.width ? getWidth(item.width) : '0px'};
                        flex-grow: ${item.width ? '0' : item.col ? item.col : '1'};
                        text-align: ${item.align ? item.align : 'left'};
                    `
                    html.push('<div class="sand-tableCollapse__header--item" style="' + style + '">')
                    html.push(' <span class="sand-tableCollapse__header--text">')
                    html.push(collapse[item.prop])
                    html.push(' </span>')
                    html.push('</div>')
                })

                html.push('  </label>')
                html.push(' <div class="my-collapse-item__content">')

                html.push(summarySlot(collapse))

                html.push(' </div>')
                html.push(' </div>')
                html.push(" </div>")
                html.push("</div>")
            })
            html.push('</div>')

            $('#summary-content').html(html.join(''))
        }

        const summarySlot = (cdata) => {
            const pid = cdata.id
            const html = []

            const elId = 'event-wrap__' + eventType + pid
            const inputId = 'event-input__' + eventType + pid
            const pageId = 'event-page__' + eventType + pid

            html.push('<div class="behavior-event-filter">')
            html.push(`
                    <div class="filter-input">
                        <div class="input-search" id="${inputId}">
                            <input type="text" placeholder="输入内容以搜索事件"/>
                            <i class="fa fa-search"></i>
                        </div>
                   </div>
                   <div>
                        <div class="page-wrap" id="${pageId}"></div>
                   </div>
            `)
            html.push('</div>')

            html.push('<div class="behavior-event-wrap" id="'+ elId+ '"')
            html.push('</div>')


            const loadFn = (page) => {
                $.get(ctx + `serve/sandboxBehaviorEventsByPid/${taskId}/${pid}/${eventType}`, {
                    page: page,
                    size: 50
                }, function(res) {
                    const events = res.data.events[eventType]
                    const count = res.data.count

                    laypage({
                        cont: pageId,
                        curr: page,
                        pages: Math.ceil(count / 50),
                        jump: function(obj, first){
                            if(!first) {
                                loadFn(obj.curr)
                            }
                        }
                    })


                    if(!events || events.le === 0) {
                        $('#' + elId).html('未搜到结果')
                        return
                    }
                    const listHtml = []
                    events.forEach(item => {
                        listHtml.push('<div class="behavior-event-item">')
                        listHtml.push('     <div class="behavior-event-left">')
                        listHtml.push('         <span class="event-name">' + (eventList[item.event] && eventList[item.event].zhcn) || item.event + '</span>')
                        listHtml.push('     </div>')
                        listHtml.push('     <div class="behavior-event-right">')
                        listHtml.push('          <div class="behavior-event-right_mainkey">' + (item.mainkey || '') + '</div>')
                        listHtml.push('     </div>')
                        listHtml.push('</div>')
                    })

                    $('#' + elId).html(listHtml.join(''))

                })
            }

            setTimeout(() => {
                loadFn(1)
                $('#' + inputId).find('input').on('enter', function() {
                    loadFn(1)
                })
                $('#' + inputId).find('.fa').on('click', function() {
                    loadFn(1)
                })
            }, 300)

            return html.join('')
        }

        buildTabs()
        SandTableCollapse2(collapseData);

    }

    /* ---------- 静态分析--------------*/


</script>
</html>